import json
import re

import requests
from django.core.paginator import Paginator
from django_redis import get_redis_connection
from rest_framework.generics import ListAPIView
from rest_framework_jwt.utils import jwt_decode_handler

from apps.food.models import Foods, DoSing, MethodOfWork, FoodCategory
from apps.serializers.user import UserPublishSerializer
from apps.tool import get_qinius
from apps.uitls.token import Verify
from apps.user.models import User, UserLike, UserCollect, UserFeedBack
from apps.user.secret_key import APPID, APPSERET  # 小程序的appid和你在微信上注册小程序开发的appseret

from rest_framework.response import Response
from rest_framework.views import APIView


def reg(username, openid, img_url):
    user = User.objects.create_user(username=username, password="", user_img=img_url, openid=openid)
    return user


class Login(APIView):
    def post(self, request):
        code = request.data.get("code")
        username = request.data.get("username")
        img_url = request.data.get("user_img")
        if not all([code, username, img_url]):
            return Response({"code": "404", "errmsg": "错误"})

        url = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type" \
              "=authorization_code" % (APPID, APPSERET, code)
        tokon = requests.get(url)
        # 获取用户openid
        data = json.loads(tokon.text)
        openid = data.get("openid")
        # 判断是否获取成功
        if not openid:
            return Response({"data": "登录失败"})
        user = User.objects.filter(openid=openid)
        # 判断数据库中是否存在该用户，如果没有则调用注册函数
        if not user:
            user = reg(username, openid, img_url)
        else:
            user = user[0]
        # 服务器生成jwt token, 保存当前用户的身份信息
        from rest_framework_jwt.settings import api_settings

        # 组织payload数据的方法
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        # 生成jwt token数据的方法
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
        # 组织payload数据
        payload = jwt_payload_handler(user)
        # 生成jwt token
        token = jwt_encode_handler(payload)

        return Response(data={"jwt": token})


class UserLikes(APIView):
    def get(self, request, pk):
        jwt = request.META.get("HTTP_JWT")
        if not jwt:
            return Response({"status": 402, "data": "未登录", "like": False, "collect": False})
        user = Verify(jwt)
        if not user:
            return Response({"status": 402, "data": "token过期了", "like": False, "collect": False})
        user_id = user.get("user_id")
        cooklike = UserLike.objects.filter(user_id=user_id, food_id=pk, is_del=False)
        cookcollect = UserCollect.objects.filter(user_id=user_id, food_id=pk, is_del=False)
        return Response({"like": True if cooklike else False, "collect": True if cookcollect else False})

    def post(self, request, pk):
        state = request.data.get("state")
        jwt = request.data.get("jwt")

        if not all([jwt, pk, state]):
            return Response({"status": 402, "msg": "请先登录"})
        user = Verify(jwt)
        if not user:
            return Response({"status": 402, "msg": "token过期了"})
        # 在数据库中获取该点赞是否存在
        user_id = user.get("user_id")
        if state == "0":
            msg = "点赞"
            userlike = UserLike.objects.filter(user_id=user_id, food_id=pk)
        else:
            msg = "收藏"
            userlike = UserCollect.objects.filter(user_id=user_id, food_id=pk)
        # 如果存在着相关is_del的内容
        status = 0
        if userlike:
            if userlike[0].is_del:
                userlike[0].is_del = False
                msg += "成功"
            else:
                status = 1
                userlike[0].is_del = True
                msg += "取消成功"
            userlike[0].save()
        # 如果不存在，则添加记录
        else:
            if state == 0:
                userlike = UserLike(user_id=user_id, food_id=pk)
            else:
                userlike = UserCollect(user_id=user_id, food_id=pk)
            msg += "成功"
            userlike.save()
        return Response({"status": 0, "msg": msg, "code": status})


class User_Collect(APIView):
    def get(self, request):
        page = int(request.GET.get("page", 1))
        jwt = request.META.get("HTTP_JWT")
        print(request.META)
        print(jwt)
        user = Verify(jwt)
        print(user)
        if not user:
            return Response({"code": 402, "msg": "请先登录"})
        usercollect = UserCollect.objects.filter(user_id=user.get("user_id"), is_del=False)
        # 创建分页器
        paginator = Paginator(usercollect, 5)

        # 判断页数是否大于总页数
        if page > paginator.num_pages:
            page = paginator.num_pages
        # 获取数据
        page_food = paginator.page(page)

        lists = []
        for i in page_food:
            collect_num = UserCollect.objects.filter(food_id=i.food.id, is_del=False).count()

            lists.append(
                {"id": i.food.id, "default_image": i.food.default_image, "name": i.food.name, "title": i.food.title,
                 "favoriteCount": collect_num, "viewCount": i.food.viewCount})

        return Response(data={"lists": lists, "pages": paginator.num_pages})


class UserPublish(ListAPIView):
    # 指定序列化器类
    serializer_class = UserPublishSerializer

    def get_queryset(self):
        """返回视图所使用的查询集"""
        jwt = self.request.META.get("HTTP_JWT")

        if not jwt:
            return Response()
        try:
            user = Verify(jwt)
        except:
            return Response

        return Foods.objects.filter(user_id=user.get("user_id"))


class UserHistory(APIView):
    def get(self, request):
        print(request.META.get("HTTP_JWT"))
        try:
            user = Verify(request.META.get("HTTP_JWT"))
        except:
            return Response()
        """获取用户浏览记录"""
        # 获取Redis存储的sku_id列表信息
        redis_conn = get_redis_connection('default')
        # 获取redis数据库中用户的所有数据
        history = redis_conn.lrange('history_%s' % user.get("user_id"), 0, -1)
        data = []
        # 循环redis数据库中的列表数据
        for i in history:
            history_food = Foods.objects.filter(id=i)
            if history_food:
                data.append(
                    {"name": history_food[0].name, "title": history_food[0].title, "collect": history_food[0].collect,
                     "default_image": history_food[0].default_image, "viewCount": history_food[0].viewCount})
        return Response({"data": data})


class UserFeedback(APIView):
    def post(self, request):
        # 获取数据
        phone = request.data.get("concat")
        content = request.data.get("content")
        index = request.data.get("index")
        user_id = request.data.get("user_id")
        if not user_id:
            user_id = 1
        # 判断数据是否足够
        if not all([phone, content, index if index != 0 else True, user_id]):
            return Response({"msg": "缺少数据"})
        phone = re.match(r"^1[3-9]\d{9}", phone)
        if not phone:
            return Response({"msg": "手机号错误"})
        phone = str(phone.group())

        # 将数据插入到数据库
        try:
            userfeed = UserFeedBack(user_id=user_id, phone=phone, feedback_id=index+1, connet=content)
            userfeed.save()
        except:
            return Response({"msg": "未知错误，留言失败"})
        return Response({"msg": "留言成功"})


class GetQiNiu(APIView):
    def get(self, request):

        print(request.GET)
        user_id = request.GET.get("user_id")
        token = get_qinius.main()
        print(token)
        return Response({"token": token})


class UserAddCook(APIView):
    def post(self, request):
        name = request.data.get("title")
        images = request.data.get("images")
        category = request.data.get("type")
        dosing_list = request.data.get("lists")
        food_list = request.data.get("steps")
        user_id = request.data.get("user_id")

        if not all([name, images, category, food_list, dosing_list, user_id]):
            return Response({"msg": "缺少数据"})
        try:
            # 获取图片
            defult = json.loads(images[0])
            img_url = get_qinius.qiniu_url + defult["hash"]
            food = Foods(name=name, title=name, default_image=img_url, user_id=user_id)
            food.save()
            # 将配料列表数据循环获取
            for i in dosing_list:
                food_dosing = DoSing(name=i["name"], num=i["attr"], food=food)
                food_dosing.save()
            num = 1
            # 获取做法列表数据
            for i in food_list:
                img_num = len(images)-1
                url = ""
                if img_num >= num:
                    url = json.loads(images[num])
                    url = get_qinius.qiniu_url + url["hash"]
                method = MethodOfWork(titles=i["name"], default_image=url, food=food, sequence=num)
                method.save()
                num += 1
            foodcate = FoodCategory(food=food, category_id=category)
            foodcate.save()
        except:
            return Response({"msg": "未知错误，添加菜谱失败"})
        return Response({"msg": "添加成功"})
